package cn.wawi.common.base;

import java.sql.Connection;
import java.util.List;
import java.util.Properties;
import org.apache.ibatis.builder.SqlSourceBuilder;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.reflection.DefaultReflectorFactory;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.ReflectorFactory;
import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
import org.apache.ibatis.reflection.factory.ObjectFactory;
import org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory;
import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;
import org.apache.ibatis.session.Configuration;

@Intercepts({@Signature(type=StatementHandler.class,method="prepare",args={Connection.class,Integer.class})})
public class MybatisInterceptor implements Interceptor{

	public static final ObjectFactory DEFAULT_OBJECT_FACTORY=new DefaultObjectFactory();
	public static final ObjectWrapperFactory DEFAULT_WRAP_OBJECT_FACTORY=new DefaultObjectWrapperFactory();
	public static final ReflectorFactory DEFAULT_REFLECTOR_FACTORY=new DefaultReflectorFactory();

	
	@Override
	public Object intercept(Invocation invocation) throws Throwable {
		StatementHandler statementHandler=(org.apache.ibatis.executor.statement.StatementHandler) invocation.getTarget();
		MetaObject metaStatementHandler=MetaObject.forObject(statementHandler, DEFAULT_OBJECT_FACTORY, DEFAULT_WRAP_OBJECT_FACTORY,DEFAULT_REFLECTOR_FACTORY);
        // 分离最后一个代理对象的目标类
        while (metaStatementHandler.hasGetter("target")) {
            Object object = metaStatementHandler.getValue("target");
    		metaStatementHandler=MetaObject.forObject(object, DEFAULT_OBJECT_FACTORY, DEFAULT_WRAP_OBJECT_FACTORY,DEFAULT_REFLECTOR_FACTORY);
        }
        String originalSql = (String) metaStatementHandler.getValue("delegate.boundSql.sql");
        Configuration configuration = (Configuration) metaStatementHandler.getValue("delegate.configuration");
        Object parameterObject = metaStatementHandler.getValue("delegate.boundSql.parameterObject");
      System.out.println("原始sql:"+originalSql);
        if (null == originalSql || "".equals(originalSql)) {
            String newSql = "";
            MappedStatement mappedStatement = (MappedStatement) metaStatementHandler
                    .getValue("delegate.mappedStatement");
            // 根据ID生成相应类型的sql语句（id需剔除namespace信息）
            String id = mappedStatement.getId();
            id=id.substring(id.lastIndexOf(".")+1);
            System.out.println("id:"+id);
            if("id".equals("findAll")){
            	newSql="select * from sys_user";
            }
            SqlSource sqlSource = buildSqlSource(configuration, newSql, parameterObject.getClass());
            List<ParameterMapping> parameterMappings = sqlSource.getBoundSql(parameterObject).getParameterMappings();
            metaStatementHandler.setValue("delegate.boundSql.sql", sqlSource.getBoundSql(parameterObject).getSql());
            metaStatementHandler.setValue("delegate.boundSql.parameterMappings", parameterMappings);
        }
        
        // 传递给下一个拦截器处理
        return invocation.proceed();
	}

	@Override
	public Object plugin(Object target) {
		if(target instanceof StatementHandler){
			return Plugin.wrap(target, this);
		}
		return target;
	}

	@Override
	public void setProperties(Properties properties) {
		
	}
    private SqlSource buildSqlSource(Configuration configuration, String originalSql, 
    Class<?> parameterType) {
        SqlSourceBuilder builder = new SqlSourceBuilder(configuration);
        return builder.parse(originalSql, parameterType, null);
    }
}
